grammar Cymbol;

compilationUnit // [编译单元]
    :   (structDeclaration | methodDeclaration | varDeclaration)+
    ;

structDeclaration // [结构体定义]
	:	'struct' ID '{' structMember+ '}' ';'
	;
	
structMember
	:	type ID ';'         #fieldDeclaration       // [变量定义]
	|	type ID ARRAY ';'   #fieldArrayDeclaration  // [数组定义]
	|	structDeclaration   #innerStructDeclaration // 直接Visit
	;

// START: method
methodDeclaration   // [方法定义]
    :   type ID '(' formalParameters? ')' block
    ;
// END: method

formalParameters  // [参数列表]
    :   parameter (',' parameter)*
    ;

parameter
	:	type ID         #varParam    // [变量定义]
	|	type ID ARRAY   #arrayParam  // [数组定义]
	;

type // [类型引用]
    :	primitiveType   #basicType
    |	'struct' ID     #structType
	;

primitiveType
	:   'float'
    |   'int'
    |	'char'
    |	'boolean'
    |	'void'
    ;


// START: block
block // [代码块]
    :   '{' statement* '}'
    ;
// END: block

// START: var
varDeclaration
    :   type ID ('=' expression)? ';'        #varDecl       // [变量定义]
    |   type ID ARRAY ('=' expression)? ';'  #arrayDecl     // [数组定义]
    ;
// END: var

statement
    :   block                                                 #blockStatement   // 直接Visit
    |   structDeclaration                                     #strcutStatement  // 直接Visit
    |	varDeclaration                                        #varStatement     // 直接Visit
    |   'if' '(' condition=expression ')' trueStatement=statement 
        ('else' falseStatement=statement)?                    #ifStatement      // [判断语句]
    |   'return' expression? ';'                              #returnStatement  // [返回语句]
    |   postfixExpression '=' expression ';'                  #assignStatement  // [赋值语句]
    |   postfixExpression ';'                                 #callStatement    // 直接Visit. handles function calls like f(i);
    ;

expressionList // [表达式列表]
    :   expression (',' expression)*
    ;

expression // 表达式类
    :   postfixExpression               #callExpression             // 直接Visit
            
    |   '-' expression                  #minusExpression            // [负数表达式]
    |   '!' expression                  #notExpression              // [取反表达式]
    
    |   expression '*' expression       #multiplicationExpression   // [乘法表达式]
    |   expression '/' expression       #divisionExpression         // [除法表达式]
    
    |   expression '+' expression       #addExpression              // [加法表达式]
    |   expression '-' expression       #subtractionExpression      // [减法表达式]
    
    |   expression '<' expression       #lessThenExpression         // [小于表达式]
    |   expression '>' expression       #greaterThenExpression      // [大于表达式]
    |   expression '<=' expression      #lessOrEqualExpression      // [小于等于表达式]
    |   expression '>=' expression      #greaterOrEqualExpression   // [大于等于表达式]
    
    |   expression '!=' expression      #notEqualExpression         // [不等于表达式]
    |   expression '==' expression      #equalExpression            // [相等表达式]
    ;


// START: call
postfixExpression   // 后缀表达式类
    :   primary
    |   postfixExpression postfix
    ;
// END: call

primary
    :   ID
    |   INT
    |	FLOAT
    |	CHAR
    |	BOOL
    |   '(' expression ')'      // 直接visit
    ;

postfix
    :   '(' expressionList? ')'     #functionCall       // [函数调用表达式]
    |   '[' expression ']'          #arrayAccess        // [数组访问表达式]
    |   '.' ID                      #memberAccess       // [成员访问表达式]
    ;


// LEXER RULES

BOOL
    :   'true'
    |   'false'
    ;

ID  :   LETTER (LETTER | '0'..'9')*
    ;


ARRAY : '[]';

fragment
LETTER  :   ('a'..'z' | 'A'..'Z')
    ;

CHAR:	'\'' . '\'' ;

INT :   '0'..'9'+
    ;

FLOAT
	:	INT '.' INT*
	|	'.' INT+
	;

WS  :   (' '|'\r'|'\t'|'\n') -> skip
    ;

SL_COMMENT
    :   '//' ~('\r'|'\n')* '\r'? '\n' -> skip
    ;
